//
//  RatingStar.swift
//  Swift-Codedase
//
//  Created by xyanl on 2024/1/23.
//  Copyright © 2024 考拉🐨. All rights reserved.
//
/**
 let ratingStarView = RatingStar(frame: CGRect(x: 114, y: 300, width: 200, height: 0))
 初始化的时候，传入的height是不好使的，height是和星星⭐️的宽度一样的
 */
import UIKit

/// 评分显示样式
enum RatingStyle {
    /// 不限制
    case none
    /// 半个
    case half
    /// 满
    case full
}

protocol RatingStarDelegate: AnyObject {
    func ratingDidChange(_ view: RatingStar, rating: CGFloat)
}

class RatingStar: UIView {
    /// 当前数值
    var rating: CGFloat = 0 {
        didSet{
            if rating < ratingMin { 
                rating = ratingMin
            } else if rating > CGFloat(starCount) {
                rating = CGFloat(starCount)
            }
            
            if style != .none {
                // 有限制
                // 将double类型，拆分成 整数和小数2部分
                let aNumber = modf(rating)
                // print("整数：\(aNumber.0) 小数：\(aNumber.1)")
                // 有小数，
                if aNumber.1 > 0 {
                    // 整数
                    let integer = aNumber.0
                    // 取小数
                    let decimals = aNumber.1
                    
                    if decimals > 0 {
                        
                        if style == .half {
                            if decimals > 0.5 {
                                // 超过一半，算整个
                                rating = integer + 1.0
                            } else {
                                // 不超一个，算半个
                                rating = integer + 0.5
                            }  
                        } else {
                            // 整星
                            if decimals > 0.1 {
                                // 超过一半，算整个
                                rating = integer + 1.0
                            }  
                            // rating = round(rating)
                        }
                    }
                }
            }
            
            //回调给代理
            delegate?.ratingDidChange(self, rating: rating)
            
            self.setNeedsLayout()
        }
    }
    
    /// ⭐️显示的最小颗粒
    var style: RatingStyle = .none
    /// 最小评分数
    var ratingMin: CGFloat = 0
    /// 星星数量
    var starCount: Int = 5 
    /// 是否开启动画模式
    var isAnimation: Bool = false
    /// 动画时间
    var animationTimeInterval: TimeInterval = 0.2
    /// true: 可以操作，用于评分。false: 不可以操作，用于显示。
    var isEnable: Bool = true
    /// 星星之间的间隔
    var space: CGFloat = 4
    
    // SVG，将源文件加入到 Assets.xcassets，然后更改 scales 为 Single scale，svg 就可以直接 UIImage(named: "svg_wujiaoxing") 使用
    var imageLight: UIImage = UIImage(named: "svg_star")!.withTintColor(UIColor(hex: "#FF6D01"))
    var imageDark: UIImage = UIImage(named: "svg_star")!.withTintColor(UIColor(hex: "#EEEEEE"))
    
    // var imageLight: UIImage = UIImage(named: "ic_ratingStar_light")!
    // var imageDark: UIImage = UIImage(named: "ic_ratingStar_dark")!
    
    weak var delegate: RatingStarDelegate?
    
    private var foregroundRatingView: UIView!
    private var backgroundRatingView: UIView!
    // 防止多次创建
    private var isDrew = false
    
    private func buildView() {
        if isDrew {
            return
        }
        isDrew = true
        // 创建前后两个View，作用是通过rating数值显示或者隐藏 “foregroundRatingView” 来改变ratingStar的星星效果
        backgroundRatingView = createRatingView(image: imageDark)
        foregroundRatingView = createRatingView(image: imageLight)
        animationRatingChange()
        addSubview(backgroundRatingView)
        addSubview(foregroundRatingView)
        // 加入单击手势
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(tapRateView))
        tapGesture.numberOfTapsRequired = 1
        addGestureRecognizer(tapGesture)
        
        let itemWidth = (bounds.size.width - (CGFloat(starCount) - 1) * space) / CGFloat(starCount)
        var f = frame
        f.size.height = itemWidth
        frame = f
        
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        buildView()
        let animationTimeInterval = isAnimation ? animationTimeInterval : 0
        // 开启动画改变foregroundRatingView可见范围
        UIView.animate(withDuration: animationTimeInterval, animations: {
            self.animationRatingChange()
        })
    }
    
    // 改变foregroundRatingView可见范围
    private func animationRatingChange() {
        // 单个星星的宽度
        let itemWidth = (bounds.size.width - (CGFloat(starCount) - 1) * space) / CGFloat(starCount)
        // 可见范围的宽度
        let width = itemWidth*rating + CGFloat(floorf(Float(rating)))*space
        foregroundRatingView.frame = CGRectMake(0, 0, width, itemWidth)
        
    }
    // 根据图片名，创建一列RatingView
    private func createRatingView(image: UIImage) ->UIView {
        let itemWidth = (bounds.size.width - (CGFloat(starCount) - 1) * space) / CGFloat(starCount)
        
        let view = UIView(frame: CGRect(x: 0, y: 0, width: bounds.size.width, height: itemWidth))
        view.clipsToBounds = true
        view.backgroundColor = .clear
        
        // 开始创建子Item，根据starCount总数。
        for position in 0 ..< starCount {
            let imageView = UIImageView(image: image)
            imageView.frame = CGRectMake((itemWidth + space) * CGFloat(position), 0, itemWidth, itemWidth)
            imageView.contentMode = UIView.ContentMode.scaleAspectFit
            view.addSubview(imageView)
        }
        return view
    }
    
    // 点击编辑分数后，通过手势的x坐标来设置数值
    @objc private func tapRateView(sender: UITapGestureRecognizer) {
        if !isEnable {
            // 如果是指示器，就不能交互
            return
        }
        let tapPoint = sender.location(in: self)
        let offset = tapPoint.x
        // 单个星星的宽度
        let itemWidth = (bounds.size.width - (CGFloat(starCount) - 1) * space) / CGFloat(starCount)
        // 通过x坐标判断分数
        let realRatingScore = offset / (itemWidth + space)
        // 当前分数
        rating = realRatingScore
        
    }
}
